import os
import pathlib
import pickle

from kivy import Logger
from kivy.lang.builder import Builder

work_path = os.getcwd()
try:
    with open("ui/cache/ui.data", "rb") as ff:
        kv_cache = pickle.load(ff)
except Exception as err:
    _ = err
    kv_cache = dict()


class KvLoad:
    __slots__ = ()

    @staticmethod
    def load(py_file: str, **kwargs) -> None:
        kv_file = None
        try:
            if py_file.endswith(".py"):
                kv_file = py_file.replace(".py", ".kv")
            else:
                kv_file = py_file.replace(".pyc", ".kv")
            if kv_file in Builder.files:
                return

            _, r_name = os.path.abspath(kv_file).split(work_path)
            kv = kv_cache.get(r_name)
            kwargs['filename'] = kv_file
            if kv:
                Builder.load_string(kv, **kwargs)
            else:
                with open(kv_file, "r", encoding="utf-8") as fd:
                    Builder.load_string(fd.read(), **kwargs)
        except Exception as e:
            Logger.error("Load {} file error:{}".format(kv_file, e))


def make_ui_cache(app_path):
    """生产kV缓存数据"""
    cache_dict = dict()
    kv_imports = set()
    kv_root = pathlib.Path(os.path.realpath(__file__)).parent.parent
    Logger.info("kv file root:{}".format(kv_root))
    cache_path = os.path.join(kv_root, "ui\\cache")
    if not os.path.exists(cache_path):
        os.mkdir(cache_path)
    ui_cache_file = os.path.join(cache_path, "ui.data")
    Logger.info("kv cache file:{}".format(ui_cache_file))
    with open(ui_cache_file, "wb") as f:
        for root, dirs, files in os.walk(kv_root):
            for file in files:
                if not file.endswith(".kv"):
                    continue
                file_all = os.path.abspath(os.path.join(root, file))
                Logger.info("loading kv file:{}".format(file_all))
                with open(file_all, 'r', encoding="utf-8") as k_file:
                    _, file_key = file_all.split(app_path)
                    kv = str(k_file.read())

                    # 收集kv 导入模块
                    for line in kv.split('\n'):
                        try:
                            command = ":import "
                            if command not in line:
                                continue
                            _, mod = line.split(command)
                            _, mod = mod.split(" ")
                            mod and kv_imports.add(mod.strip())
                        except Exception as e:
                            Logger.error("collect kv file import error:{}".format(e))

                    cache_dict[file_key] = kv
        Logger.info("dump data...")
        pickle.dump(cache_dict, f)
        Logger.info("kv imports:{}".format(kv_imports))
        return cache_dict, list(kv_imports)
